package com.cardone.platform.configuration.service;

import com.cardone.common.service.SimpleDefaultService;
import com.cardone.common.util.ExcelUtils;
import com.cardone.context.Attributes;
import com.cardone.context.ContextHolder;
import com.cardone.platform.common.util.EntityFileUtils;
import com.cardone.platform.configuration.dao.DictionaryDao;
import com.cardone.platform.configuration.dao.DictionaryTypeDao;
import com.cardone.platform.configuration.dto.DictionaryDto;
import com.cardone.platform.configuration.dto.DictionaryTypeDto;
import com.cardone.platform.configuration.po.DictionaryType;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.util.*;

/**
 * 字典类型服务
 *
 * @author yaohaitao
 */
@Getter
@Setter
@Transactional(readOnly = true)
public class DictionaryTypeDefaultService extends SimpleDefaultService<DictionaryTypeDto> implements DictionaryTypeService {
    @Override
    public DictionaryTypeDao getDao() {
        return ContextHolder.getBean(DictionaryTypeDao.class);
    }

    @Override
    @org.springframework.transaction.annotation.Transactional(readOnly = true)
    public <P> List<P> findListByParentId(final Class<P> mappedClass, final String parentId) {
        return ContextHolder.getBean(DictionaryTypeDao.class).findListByParentId(mappedClass, parentId);
    }

    @Override
    @org.springframework.transaction.annotation.Transactional(readOnly = true)
    public <P> List<P> findListByParentCode(final Class<P> mappedClass, final String parentCode) {
        return ContextHolder.getBean(DictionaryTypeDao.class).findListByParentCode(mappedClass, parentCode);
    }

    @Override
    @Transactional
    @CacheEvict(value = DictionaryTypeService.BEAN_ID, allEntries = true)
    public void init() {
        this.init(DictionaryType.class.getName() + ".initList");
    }

    @Override
    @Transactional
    public void importExcel(final String filename) throws Exception {
        final File file = new File(filename);

        EntityFileUtils.writeTo(file, filename);

        final Map<Integer, String> columns0 = Maps.newHashMap();

        columns0.put(0, Attributes.typeId.name());
        columns0.put(1, Attributes.typeCode.name());
        columns0.put(2, Attributes.typeName.name());
        columns0.put(3, "typeOrderNum");
        columns0.put(4, Attributes.id.name());
        columns0.put(5, Attributes.code.name());
        columns0.put(6, Attributes.name.name());
        columns0.put(7, Attributes.remark.name());
        columns0.put(8, "explainText");
        columns0.put(9, Attributes.orderNum.name());

        final ExcelUtils.ExcelConfig excelConfig0 = ExcelUtils.ExcelConfig.newExcelConfig(columns0);

        excelConfig0.setFirstRowIndex(1);
        excelConfig0.setSheetIndexs(new int[]{0});

        ExcelUtils.readFile(file, Lists.newArrayList(excelConfig0));

        final List<DictionaryTypeDto> dictionaryTypeList = Lists.newArrayList();

        final Map<String, DictionaryTypeDto> dictionaryTypeMap = Maps.newHashMap();

        int dictonaryOrderNum = 0;

        int dictonaryTypeOrderNum = 0;

        for (final Map<String, Object> data : excelConfig0.getDataList()) {
            final String typeId = MapUtils.getString(data, Attributes.typeId.name());
            final String typeCode = MapUtils.getString(data, Attributes.typeCode.name());
            final String typeName = MapUtils.getString(data, Attributes.typeName.name());
            final Double typeOrderNum = MapUtils.getDouble(data, "typeOrderNum");
            final String id = MapUtils.getString(data, Attributes.id.name());
            final String code = MapUtils.getString(data, Attributes.code.name());
            final String name = MapUtils.getString(data, Attributes.name.name());
            final String remark = MapUtils.getString(data, Attributes.remark.name());
            final String explainText = MapUtils.getString(data, "explainText");
            final Double orderNum = MapUtils.getDouble(data, Attributes.orderNum.name());

            DictionaryTypeDto dictionaryType = dictionaryTypeMap.get(typeCode);

            if (dictionaryType == null) {
                dictionaryType = new DictionaryTypeDto();

                dictionaryType.setId(typeId);

                dictionaryType.setCode(typeCode).setName(StringUtils.trim(typeName));

                if (typeOrderNum == null) {
                    dictionaryType.setOrderNum(new Double(dictonaryTypeOrderNum++));
                } else {
                    dictionaryType.setOrderNum(typeOrderNum);
                }

                dictionaryType.setDictionaryList(Lists.<DictionaryDto>newArrayList());

                dictionaryTypeMap.put(typeCode, dictionaryType);

                dictionaryTypeList.add(dictionaryType);

                dictonaryOrderNum = 0;
            }

            final DictionaryDto dictionary = new DictionaryDto();

            dictionary.setId(id).setCode(code).setName(StringUtils.trim(name));

            dictionary.setRemark(remark).setExplainText(explainText);

            if (typeOrderNum == null) {
                dictionary.setOrderNum(new Double(dictonaryOrderNum++));
            } else {
                dictionary.setOrderNum(orderNum);
            }

            dictionaryType.getDictionaryList().add(dictionary);
        }

       this.init(dictionaryTypeList);
    }

    public void init(final List<DictionaryTypeDto> initDictionaryTypeList) {
        if (CollectionUtils.isEmpty(initDictionaryTypeList)) {
            return;
        }

        for (final DictionaryTypeDto initDictionaryType : initDictionaryTypeList) {
            final DictionaryTypeDto oldDictionaryType = ContextHolder.getBean(DictionaryTypeDao.class).saveByIdOrCode(DictionaryTypeDto.class, initDictionaryType);

            if (!CollectionUtils.isEmpty(initDictionaryType.getDictionaryList())) {
                for (final DictionaryDto initDictionary : initDictionaryType.getDictionaryList()) {
                    initDictionary.setTypeId(oldDictionaryType.getId());

                    ContextHolder.getBean(DictionaryDao.class).saveByIdOrCode(DictionaryDto.class, initDictionary);
                }
            }

            if (CollectionUtils.isEmpty(initDictionaryType.getChilds())) {
                continue;
            }

            for (final DictionaryTypeDto childDictionaryTy : initDictionaryType.getChilds()) {
                childDictionaryTy.setParentId(oldDictionaryType.getId());
            }

            this.init(initDictionaryType.getChilds());
        }
    }
}